package com.bsg.upm.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.check.ServCheck;
import com.bsg.upm.constant.DictConstants;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.constant.SubTaskDictConstants;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.constant.TaskDictConstants;
import com.bsg.upm.constant.TaskDictTypeConstants;
import com.bsg.upm.dto.ServDto;
import com.bsg.upm.dto.SubServDto;
import com.bsg.upm.dto.UnitDto;
import com.bsg.upm.entity.AreaEntity;
import com.bsg.upm.entity.BusinessSubSystemEntity;
import com.bsg.upm.entity.DefinitionSubTaskConfigEntity;
import com.bsg.upm.entity.OperateLogEntity;
import com.bsg.upm.entity.OrderEntity;
import com.bsg.upm.entity.ServEntity;
import com.bsg.upm.entity.SubOrderEntity;
import com.bsg.upm.entity.SubServEntity;
import com.bsg.upm.entity.SubTaskEntity;
import com.bsg.upm.entity.TaskEntity;
import com.bsg.upm.entity.UnitEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.excel.ExcelUtil;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.HttpClientUtils;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.NumberUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 服务管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class ServService extends BaseService {

	@Resource
	private ServCheck servCheck;

	@Resource
	private OrderService orderService;

	@Resource
	private SubServService subServService;

	@Resource
	private MonitorSubServService monitorSubServService;

	/**
	 * 获取服务列表
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(Map<String, Object> paramMap) throws APIException {
		try {
			// 结果集
			JSONArray results = new JSONArray();

			// 获取指定的服务集合
			List<ServEntity> servs = servDao.list(paramMap);
			if (servs.size() == 0) {
				return RespJsonFactory.buildOK(results);
			}

			// 站点集合
			List<String> siteIds = new ArrayList<>();
			for (ServEntity serv : servs) {
				String siteId = serv.getOrder().getArea().getSite().getId();
				if (!siteIds.contains(siteId)) {
					siteIds.add(siteId);
				}
			}

			// 子服务类别
			List<String> subServTypes = new ArrayList<>();
			for (ServEntity serv : servs) {
				List<SubServEntity> subServs = serv.getSubServs();
				for (SubServEntity subServ : subServs) {
					String dfSubServName = subServ.getSubOrder().getDefinitionSubServ().getName();
					if (!subServTypes.contains(dfSubServName)) {
						subServTypes.add(dfSubServName);
					}
				}
			}

			// MGM服务信息
			JSONArray mgmServInfos = new JSONArray();
			// horus服务状态信息
			Map<String, JSONArray> monitorUnitStatusMap = new HashMap<>();
			for (String siteId : siteIds) {
				// 从MGM获取指定类型的所有服务信息
				mgmServInfos.addAll(subServService.listServInfosFromMGM(siteId, subServTypes));

				for (String subServType : subServTypes) {
					try {
						monitorUnitStatusMap
								.putAll(monitorSubServService.getAllSubServStatusByType(siteId, subServType));
					} catch (Exception e) {
					}
				}
			}

			// 服务拓扑
			Map<String, JSONObject> topologyMap = getTopology(servs);

			for (ServEntity serv : servs) {
				// 构建服务展示对象
				ServDto servDto = buildShowDto(serv);
				results.add(servDto);

				// 服务状态
				String status = getServStatus(serv, monitorUnitStatusMap);
				servDto.setStatus(status);
				servDto.setStatusText(dictTypeCache.getTextFromCache(DictTypeConstants.SERV_STATUS, status));

				// 服务可用状态
				String availableStatus = getAvailableStatus(topologyMap.get(serv.getId()),
						serv.getOrder().getDefinitionServ().getCode());
				servDto.setAvailableStatus(availableStatus);
				servDto.setAvailableStatusText(
						dictTypeCache.getTextFromCache(DictTypeConstants.SERV_STATUS, availableStatus));

				// 子服务展示对象
				List<SubServDto> subServDtos = subServService.buildSubServsDto(serv, mgmServInfos, monitorUnitStatusMap,
						topologyMap.get(serv.getId()));
				servDto.setSubServs(subServDtos);
			}

			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("服务查询异常", e);
			throw new APIException("服务查询异常:" + e.getMessage());
		}
	}

	/**
	 * 服务详情
	 * 
	 * @param servId
	 *            服务编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String servId) throws APIException {
		try {
			// 获取指定的服务
			ServEntity serv = servDao.get(servId);
			if (serv == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该服务不存在");
			}

			// 构建服务展示对象
			ServDto servDto = buildShowDto(serv);

			String siteId = serv.getOrder().getArea().getSite().getId();
			Map<String, JSONArray> monitorUnitStatusMap = new HashMap<>();
			List<SubServEntity> subServs = serv.getSubServs();
			for (SubServEntity subServ : subServs) {
				String metric = definitionMetricCache.getMetric(subServ.getSubOrder().getDefinitionSubServ().getName(),
						"status");
				try {
					monitorUnitStatusMap.putAll(getNohistory(siteId, metric, subServ.getRelateId()));
				} catch (APIException e) {
				}
			}

			// 服务状态
			String status = getServStatus(serv, monitorUnitStatusMap);
			servDto.setStatus(status);
			servDto.setStatusText(dictTypeCache.getTextFromCache(DictTypeConstants.SERV_STATUS, status));

			JSONArray mgmServInfos = new JSONArray();
			for (SubServEntity subServ : subServs) {
				if (StringUtils.isNotBlank(subServ.getRelateId())) {
					// 从MGM获取服务信息
					mgmServInfos.add(subServService.getServInfoFromMGM(siteId, subServ.getRelateId()));
				}
			}

			// 服务的拓扑信息
			JSONObject topologyInfo = null;
			try {
				topologyInfo = getTopology(serv);
			} catch (Exception e) {
			}

			// 服务可用状态
			String availableStatus = getAvailableStatus(topologyInfo, serv.getOrder().getDefinitionServ().getCode());
			servDto.setAvailableStatus(availableStatus);
			servDto.setAvailableStatusText(
					dictTypeCache.getTextFromCache(DictTypeConstants.SERV_STATUS, availableStatus));

			// 构建子服务展示对象
			List<SubServDto> subServDtos = subServService.buildSubServsDto(serv, mgmServInfos, monitorUnitStatusMap,
					topologyInfo);
			servDto.setSubServs(subServDtos);

			return RespJsonFactory.buildOK(servDto);
		} catch (Exception e) {
			logger.error("服务获取异常", e);
			throw new APIException("服务获取异常:" + e.getMessage());
		}
	}

	/**
	 * 服务启动
	 * 
	 * @param servId
	 *            服务编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson start(String servId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_START;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的服务
			ServEntity serv = servDao.getBase(servId);

			// 服务启动检查
			CheckResult chkRS = servCheck.checkStart(serv);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, serv.getId(),
					serv.getServName());

			// 构建服务启动任务
			TaskEntity task = buildStartServTask(serv, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务停止
	 * 
	 * @param servId
	 *            服务编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson stop(String servId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		String operateAcion = OperateDictConstants.ACTION_STOP;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			ServEntity serv = servDao.getBase(servId);

			CheckResult chkRS = servCheck.checkStop(serv);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, serv.getId(),
					serv.getServName());

			TaskEntity task = buildStopServTask(serv, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务备份
	 * 
	 * @param paramMap
	 *            请求参数
	 * @param auto
	 *            是否自动备份
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson backup(Map<String, Object> paramMap, boolean auto) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_BACKUP;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 备份检查
			CheckResult chkRS = servCheck.checkBackup(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			String servId = (String) paramMap.get("servId");
			// 获取指定的服务
			ServEntity serv = servDao.getBase(servId);

			// 自动配置操作者为服务所属者，手动配置操作者用当前用户
			String operator = getUser().getUsername();
			if (auto) {
				operator = serv.getOrder().getOwner();
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 操作日志对象
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, serv.getId(),
					serv.getServName(), operator, systemDao.getCurrentDateTime());

			// 构建服务备份任务
			TaskEntity task = buildBackupServTask(serv, paramMap, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务变更 包括服务扩容/版本变更
	 * 
	 * @param paramMap
	 *            请求参数
	 * @param type
	 *            变更类型
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson update(Map<String, Object> paramMap, String type) throws APIException {
		if (StringUtils.isBlank(type)) {
			return RespJsonFactory.build(HttpStatus.SC_BAD_REQUEST, "变更类型不存在");
		}
		switch (type) {
		case DictConstants.ORDER_TYPE_SCALE_UP:
			return scaleUpServ(paramMap);
		case DictConstants.ORDER_TYPE_IMAGE_UPDATE:
			return updateImageVersion(paramMap);
		default:
			return RespJsonFactory.build(HttpStatus.SC_BAD_REQUEST, "变更类型不存在");
		}
	}

	/**
	 * 服务扩容
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	private RespJson scaleUpServ(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_SCALE_UP;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 扩容检查
			CheckResult chkRS = servCheck.checkScaleUp(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 构建扩容工单
			OrderEntity scaleUpOrder = buildChangedOrder(paramMap, DictConstants.ORDER_TYPE_SCALE_UP);
			orderService.saveOrderDetail(scaleUpOrder);

			String servId = (String) paramMap.get("servId");
			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, servId,
					scaleUpOrder.getServName(), scaleUpOrder.getCreateDateTime());

			// 自动审批
			boolean autoApprove = orderService.isAutoApprove();
			if (!autoApprove) {
				txManager.commit(txStatus);
				return RespJsonFactory.buildOK();
			}

			// 设置工单状态
			scaleUpOrder.setStatus(DictConstants.ORDER_STATUS_EXECUTED);
			orderDao.updateStatusAndMsg(scaleUpOrder);

			// 构建变更后的服务
			ServEntity serv = orderService.buildChangedServ(scaleUpOrder);
			orderService.updateServDetail(serv);

			// 构建服务扩容任务
			TaskEntity task = orderService.buildScaleUpServTask(serv, operateLog);
			saveTask(task);

			txManager.commit(txStatus);

			startTask(task);
			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 版本变更
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	private RespJson updateImageVersion(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_IMAGE_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 扩容检查
			CheckResult chkRS = servCheck.checkUpdateImageVersion(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 构建版本变更工单
			OrderEntity updateImageVersionOrder = buildChangedOrder(paramMap, DictConstants.ORDER_TYPE_IMAGE_UPDATE);
			orderService.saveOrderDetail(updateImageVersionOrder);

			String servId = (String) paramMap.get("servId");
			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, servId,
					updateImageVersionOrder.getServName(), updateImageVersionOrder.getCreateDateTime());

			// 自动审批
			boolean autoApprove = orderService.isAutoApprove();
			if (!autoApprove) {
				txManager.commit(txStatus);
				return RespJsonFactory.buildOK();
			}

			// 设置工单状态
			updateImageVersionOrder.setStatus(DictConstants.ORDER_STATUS_EXECUTED);
			orderDao.updateStatusAndMsg(updateImageVersionOrder);

			// 构建变更后的服务
			ServEntity serv = orderService.buildChangedServ(updateImageVersionOrder);
			orderService.updateServDetail(serv);

			// 构建服务版本变更任务
			TaskEntity task = orderService.buildUpdateImageVersionTask(serv, operateLog);
			saveTask(task);

			txManager.commit(txStatus);

			startTask(task);
			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务重建
	 *
	 * @param servId
	 *            服务编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson rebuild(String servId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		String operateAcion = OperateDictConstants.ACTION_REBUILD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			ServEntity serv = servDao.get(servId);

			CheckResult chkRS = servCheck.checkRebuild(serv);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, serv.getId(),
					serv.getServName());

			TaskEntity task = buildRebuildServTask(serv, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);
			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务删除
	 * 
	 * @param servId
	 *            服务编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson remove(String servId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REMOVE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的服务
			ServEntity serv = servDao.getBase(servId);

			// 服务删除检查
			CheckResult chkRS = servCheck.checkRemove(serv);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_SERV, operateAcion, serv.getId(),
					serv.getServName());

			// 构建服务删除任务
			TaskEntity task = buildRemoveServTask(serv, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);
			return RespJsonFactory.buildNoContent();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("服务" + operateAcionText + "异常", e);
			throw new APIException("服务" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 服务下载
	 * 
	 * @param filePath
	 *            模板路径
	 * @param paramMap
	 *            请求参数
	 * @return Workbook
	 * @throws APIException
	 *             API异常处理类
	 */
	@SuppressWarnings("unchecked")
	public Workbook download(String filePath, Map<String, Object> paramMap) throws APIException {
		try {
			Workbook workbook = ExcelUtil.getWorkbook(new File(filePath));
			Sheet sheet = workbook.getSheetAt(0);
			RespJson respJson = list(paramMap);
			List<ServDto> servs = (List<ServDto>) respJson.getData();
			List<UserEntity> users = userDao.list(null);
			int titleCnt = 2;
			Row baseRow = sheet.getRow(titleCnt);
			int rowIndex = titleCnt;
			for (ServDto serv : servs) {
				Row row = sheet.getRow(rowIndex);
				if (row == null) {
					row = sheet.createRow(rowIndex);
					ExcelUtil.copyRow(workbook, baseRow, row);
				}

				row.getCell(0).setCellValue(serv.getSiteName());
				row.getCell(1).setCellValue(serv.getOwner());
				UserEntity user = findUser(users, serv.getOwner());
				if (user != null) {
					row.getCell(2).setCellValue(user.getName());
					row.getCell(3).setCellValue(user.getCompany());
				}
				row.getCell(4).setCellValue(serv.getBusinessSystemName());
				row.getCell(5).setCellValue(serv.getBusinessSubSystemName());
				row.getCell(6).setCellValue(serv.getServName());

				List<SubServDto> subServs = serv.getSubServs();
				for (SubServDto subServ : subServs) {
					if ((SysConstants.SERV_UPSQL_UPPROXY_SWM_CODE.equals(serv.getType())
							&& SysConstants.SUBSERV_UPSQL_NAME.equals(subServ.getType()))
							|| (SysConstants.SERV_UPREDIS_URPROXY_SENTINEL_CODE.equals(serv.getType())
									&& SysConstants.SUBSERV_UPREDIS_NAME.equals(subServ.getType()))) {
						row.getCell(7).setCellValue(subServ.getArchName());
						row.getCell(8).setCellValue(subServ.getScaleName());
						break;
					}
				}

				row.getCell(9).setCellValue(serv.getStatusText());
				row.getCell(10).setCellValue(serv.getAvailableStatusText());

				long servBackupFileSumSize = 0;
				for (SubServDto subServ : subServs) {
					servBackupFileSumSize += subServ.getBackupFileSumSize();
				}
				row.getCell(11).setCellValue(NumberUtils.retainDigits(servBackupFileSumSize / 1024.0 / 1024 / 1024));

				row.getCell(12).setCellValue(serv.getCreateDateTime());

				int unitSum = 0;
				for (SubServDto subServ : subServs) {
					servBackupFileSumSize += subServ.getBackupFileSumSize();
					List<UnitDto> units = subServ.getUnits();
					unitSum += units.size();
					for (UnitDto unit : units) {
						row = sheet.getRow(rowIndex);
						if (row == null) {
							row = sheet.createRow(rowIndex);
							ExcelUtil.copyRow(workbook, baseRow, row);
						}
						row.getCell(13).setCellValue(unit.getRelateName());
						row.getCell(14).setCellValue(unit.getType());
						row.getCell(15).setCellValue(unit.getSoftwareVersion());
						row.getCell(16).setCellValue(unit.getServerIp());
						if (unit.getPortValue() != null) {
							row.getCell(17).setCellValue(unit.getPortValue());
						}
						if (unit.getCpuCount() != null) {
							row.getCell(18).setCellValue(unit.getCpuCount());
						}
						if (unit.getMemSize() != null) {
							row.getCell(19).setCellValue(unit.getMemSize() / 1024 / 1024 / 1024);
						}
						if (unit.getDataDirSize() != null && unit.getLogDirSize() != null) {
							row.getCell(20)
									.setCellValue((unit.getDataDirSize() + unit.getLogDirSize()) / 1024 / 1024 / 1024);
						}
						row.getCell(21).setCellValue(unit.getHostName());
						row.getCell(22).setCellValue(unit.getHostIp());
						row.getCell(23).setCellValue(unit.getClusterName());

						rowIndex++;
					}
				}
				// 合并单元格
				for (int m = 0; m < 13; m++) {
					ExcelUtil.mergeCells(sheet, rowIndex - unitSum, rowIndex - 1, m, m);
				}
			}

			// 列宽自适应
			ExcelUtil.autoSizeColumn(sheet);

			return workbook;
		} catch (Exception e) {
			logger.error("服务下载异常", e);
			throw new APIException("服务下载异常" + e.getMessage());
		}
	}

	/**
	 * 构建服务展示对象
	 * 
	 * @param serv
	 *            服务对象
	 * @return 服务展示对象
	 */
	public ServDto buildShowDto(ServEntity serv) {
		ServDto servDto = new ServDto();
		servDto.setId(serv.getId());
		AreaEntity area = serv.getOrder().getArea();
		// 站点
		servDto.setSiteId(area.getSite().getId());
		servDto.setSiteName(area.getSite().getName());
		// 区域
		servDto.setAreaName(area.getName());

		BusinessSubSystemEntity businessSubSystem = serv.getOrder().getBusinessSubSystem();
		if (businessSubSystem != null) {
			// 业务系统
			servDto.setBusinessSystemName(businessSubSystem.getBusinessSystem().getName());
			// 业务子系统
			servDto.setBusinessSubSystemName(businessSubSystem.getName());
		}
		// 服务名称
		servDto.setServName(serv.getServName());
		servDto.setType(serv.getOrder().getDefinitionServ().getCode());
		// 所属者
		servDto.setOwner(serv.getOrder().getOwner());
		// 分片结构
		servDto.setSharding(serv.getOrder().getSharding());
		// 创建时间
		servDto.setCreateDateTime(DateUtils.dateTimeToString(serv.getCreateDateTime()));
		// 任务状态
		List<TaskEntity> tasks = serv.getTasks();
		if (tasks != null && tasks.size() > 0) {
			servDto.setTaskStatus(tasks.get(0).getStatus());
			servDto.setTaskStatusText(
					dictTypeCache.getTextFromCache(TaskDictTypeConstants.TASK_STATUS, servDto.getTaskStatus()));
		}
		return servDto;
	}

	/**
	 * 构建变更工单对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @param type
	 *            工单类型
	 * @return 工单对象
	 */
	@SuppressWarnings("unchecked")
	private OrderEntity buildChangedOrder(Map<String, Object> paramMap, String type) {
		String servId = (String) paramMap.get("servId");
		OrderEntity order = orderDao.getByServId(servId);
		String orderId = order.getId();
		order.setId(PrimaryKeyUtils.uniqueId());
		// 工单类型
		order.setType(type);
		// 关联工单编码
		order.setAssociateOrderId(orderId);
		// 工单状态
		order.setStatus(DictConstants.ORDER_STATUS_UNAPPROVED);

		UserEntity user = getUser();
		String username = user.getUsername();
		order.setCreateDateTime(systemDao.getCurrentDateTime());
		order.setCreateUserLoginName(username);

		// 子工单
		List<SubOrderEntity> subOrders = order.getSubOrders();
		for (SubOrderEntity subOrder : subOrders) {
			subOrder.setId(PrimaryKeyUtils.uniqueId());
			List<Map<String, Object>> dfSubServs_input = (List<Map<String, Object>>) paramMap.get("definitionSubServs");

			for (Map<String, Object> map : dfSubServs_input) {
				if (subOrder.getDefinitionSubServ().getName().equals(map.get("name"))) {
					if (DictConstants.ORDER_TYPE_SCALE_UP.equals(type)) {
						// 规模
						if (map.containsKey("scale")) {
							subOrder.setDefinitionSubServUnitScale(
									definitionSubServUnitScaleDao.get((String) map.get("scale")));
						}

						// 表空间
						if (map.containsKey("dataDirSize")) {
							subOrder.setDataDirSize((Long) map.get("dataDirSize"));
						}

						// 带宽
						if (map.containsKey("networkBandwidth")) {
							subOrder.setNetworkBandwidth((Integer) map.get("networkBandwidth"));
						}
					} else if (DictConstants.ORDER_TYPE_IMAGE_UPDATE.equals(type)) {
						// 镜像
						subOrder.setSubServSoftwareImage(
								subServSoftwareImageDao.get((String) map.get("softwareImage")));
					}
				}
			}
		}

		return order;
	}

	/**
	 * 构建启动服务任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildStartServTask(ServEntity serv, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(serv.getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_SERV);
		task.setObjId(serv.getId());
		task.setObjName(serv.getServName());
		task.setObj(serv);
		task.setActionType(TaskDictConstants.ACTION_TYPE_START);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(serv.getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_START_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildStartServSubTasks(serv, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建启动服务子任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildStartServSubTasks(ServEntity serv, Date date) {
		List<SubServEntity> subServs = serv.getSubServs();
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(subServs.size());

		sortByPriorityASC(subServs);
		int priority = 1;

		for (SubServEntity subServ : subServs) {
			if (StringUtils.isNotBlank(subServ.getRelateId())) {
				SubTaskEntity subTask = new SubTaskEntity();
				subTasks.add(subTask);

				subTask.setId(PrimaryKeyUtils.uniqueId());
				subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_SUBSERV);
				subTask.setObjId(subServ.getId());
				subTask.setObjName(subServ.getSubOrder().getDefinitionSubServ().getName());
				subTask.setObj(subServ);
				subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_START);
				subTask.setAsync(true);
				DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
						.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
				subTask.setTimeout(dfSubTaskConfig.getTimeout());
				if (priority == 1) {
					subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
					subTask.setStartDateTime(date);
				} else {
					subTask.setStatus(SubTaskDictConstants.STATUS_NOTRUN);
				}

				String url = "/" + SysConstants.MGM_VERSION + "/services/" + subServ.getRelateId() + "/start";
				subTask.setUrl(url);
				subTask.setMethodType(HttpClientUtils.METHOD_POST);
				subTask.setParam(null);
				subTask.setPriority(priority);
				priority++;
			}
		}
		return subTasks;
	}

	/**
	 * 构建停止服务任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildStopServTask(ServEntity serv, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(serv.getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_SERV);
		task.setObjId(serv.getId());
		task.setObjName(serv.getServName());
		task.setObj(serv);
		task.setActionType(TaskDictConstants.ACTION_TYPE_STOP);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(serv.getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_STOP_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildStopServSubTasks(serv, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建停止服务子任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildStopServSubTasks(ServEntity serv, Date date) {
		List<SubServEntity> subServs = serv.getSubServs();
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(subServs.size());

		sortByPriorityDESC(subServs);
		int priority = 1;

		for (SubServEntity subServ : subServs) {
			if (StringUtils.isNotBlank(subServ.getRelateId())) {
				SubTaskEntity subTask = new SubTaskEntity();
				subTasks.add(subTask);

				subTask.setId(PrimaryKeyUtils.uniqueId());
				subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_SUBSERV);
				subTask.setObjId(subServ.getId());
				subTask.setObjName(subServ.getSubOrder().getDefinitionSubServ().getName());
				subTask.setObj(subServ);
				subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_STOP);
				subTask.setAsync(true);
				DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
						.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
				subTask.setTimeout(dfSubTaskConfig.getTimeout());
				if (priority == 1) {
					subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
					subTask.setStartDateTime(date);
				} else {
					subTask.setStatus(SubTaskDictConstants.STATUS_NOTRUN);
				}
				String url = "/" + SysConstants.MGM_VERSION + "/services/" + subServ.getRelateId() + "/stop";
				subTask.setUrl(url);
				subTask.setMethodType(HttpClientUtils.METHOD_POST);
				subTask.setParam(null);
				subTask.setPriority(priority);
				priority++;
			}
		}
		return subTasks;
	}

	/**
	 * 构建服务备份任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param paramMap
	 *            请求参数
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 * @throws Exception
	 *             异常
	 */
	private TaskEntity buildBackupServTask(ServEntity serv, Map<String, Object> paramMap, OperateLogEntity operateLog)
			throws Exception {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(serv.getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_SERV);
		task.setObjId(serv.getId());
		task.setObjName(serv.getServName());
		task.setObj(serv);
		task.setActionType(TaskDictConstants.ACTION_TYPE_BACKUP);
		task.setOperateLog(operateLog);
		task.setOwner(serv.getOrder().getOwner());
		task.setCreateUserLoginName(operateLog.getCreateUserLoginName());
		task.setStatus(TaskDictConstants.STATUS_BACKUP_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildBackupServSubTasks(serv, paramMap, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建备份服务的任务的子任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param paramMap
	 *            请求参数
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 * @throws Exception
	 *             异常
	 */
	private List<SubTaskEntity> buildBackupServSubTasks(ServEntity serv, Map<String, Object> paramMap, Date date)
			throws Exception {
		Map<String, String> masterMap = getMasterUnitRelateName(serv);
		for (Map.Entry<String, String> entry : masterMap.entrySet()) {
			if (StringUtils.isBlank(entry.getValue())) {
				throw new APIException("存在分片没有主单元");
			}
		}
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>();
		List<SubServEntity> subServs = serv.getSubServs();
		for (SubServEntity subServ : subServs) {
			if (subServ.getSubOrder().getDefinitionSubServ().getCanBackup()) {
				if (StringUtils.isNotBlank(subServ.getRelateId())) {
					UnitEntity masterUnit = unitDao.getByRelateName(masterMap.get(subServ.getRelateId()));
					SubTaskEntity subTask = new SubTaskEntity();
					subTasks.add(subTask);

					subTask.setId(PrimaryKeyUtils.uniqueId());
					subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
					subTask.setObjId(masterUnit.getId());
					subTask.setObjName(masterUnit.getRelateName());
					subTask.setObj(masterUnit);
					subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_BACKUP);
					subTask.setAsync(true);
					DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
							.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
					subTask.setTimeout(dfSubTaskConfig.getTimeout());
					subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
					subTask.setStartDateTime(date);
					String url = "/" + SysConstants.MGM_VERSION + "/services/" + masterUnit.getSubServ().getRelateId()
							+ "/backup";
					subTask.setUrl(url);
					subTask.setMethodType(HttpClientUtils.METHOD_POST);
					subTask.setParam(buildBackupServParam(masterUnit, paramMap));
					subTask.setPriority(1);
				}
			}
		}
		return subTasks;
	}

	/**
	 * 构建备份服务参数
	 * 
	 * @param masterUnit
	 *            主单元对象
	 * @param paramMap
	 *            请求参数
	 * @return 备份服务参数
	 */
	private String buildBackupServParam(UnitEntity masterUnit, Map<String, Object> paramMap) {
		JSONObject param = new JSONObject();
		param.put("nameOrID", masterUnit.getRelateId());
		String type = (String) paramMap.get("type");
		if (StringUtils.isBlank(type)) {
			type = "full";
		}
		String mgmBackupType = definitionCache.getDefinitionCodeFromCache(DictTypeConstants.BACKUP_TYPE, type);
		param.put("type", mgmBackupType);

		Integer retention = (Integer) paramMap.get("retention");
		if (retention == null) {
			retention = 7;
		}
		param.put("backup_files_retention", retention);

		param.put("tag", masterUnit.getSubServ().getServ().getOrder().getOwner());
		param.put("remark", (String) paramMap.get("remark"));
		return param.toJSONString();
	}

	/**
	 * 构建重建服务任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildRebuildServTask(ServEntity serv, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(serv.getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_SERV);
		task.setObjId(serv.getId());
		task.setObjName(serv.getServName());
		task.setObj(serv);
		task.setActionType(TaskDictConstants.ACTION_TYPE_REBUILD);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(serv.getOrder().getOwner());
		task.setCreateUserLoginName(username);
		String status = null;
		switch (serv.getOrder().getType()) {
		case DictConstants.ORDER_TYPE_CREATE:
			status = TaskDictConstants.STATUS_CREATE_RUNNING;
			break;
		case DictConstants.ORDER_TYPE_SCALE_UP:
			status = TaskDictConstants.STATUS_SCALE_UP_RUNNING;
			break;
		case DictConstants.ORDER_TYPE_IMAGE_UPDATE:
			status = TaskDictConstants.STATUS_IMAGE_UPDATE_RUNNING;
			break;
		}
		task.setStatus(status);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildRebuildSubTasks(serv, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建重建服务子任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildRebuildSubTasks(ServEntity serv, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>();
		switch (serv.getOrder().getType()) {
		case DictConstants.ORDER_TYPE_CREATE:
			List<SubTaskEntity> removeSubTasks = buildRemoveSubTasks(serv, date);
			subTasks.addAll(removeSubTasks);
			int maxPriority = 0;
			for (SubTaskEntity subTask : removeSubTasks) {
				if (subTask.getPriority().intValue() > maxPriority) {
					maxPriority = subTask.getPriority().intValue();
				}
			}
			List<SubTaskEntity> createSubTasks = orderService.buildCreateServSubTasks(serv, date, maxPriority + 1);
			subTasks.addAll(createSubTasks);
			break;

		case DictConstants.ORDER_TYPE_SCALE_UP:
			subTasks = orderService.buildScaleUpServSubTasks(serv, date);
			break;
		case DictConstants.ORDER_TYPE_IMAGE_UPDATE:
			subTasks = orderService.buildUpdateImageVersionSubTasks(serv, date);
			break;
		}
		return subTasks;
	}

	/**
	 * 构建服务删除任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildRemoveServTask(ServEntity serv, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(serv.getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_SERV);
		task.setObjId(serv.getId());
		task.setObjName(serv.getServName());
		task.setObj(serv);
		task.setActionType(TaskDictConstants.ACTION_TYPE_REMOVE);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(serv.getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_REMOVE_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildRemoveSubTasks(serv, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建服务删除子任务
	 * 
	 * @param serv
	 *            服务对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildRemoveSubTasks(ServEntity serv, Date date) {
		List<SubServEntity> subServs = serv.getSubServs();
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(subServs.size());

		sortByPriorityDESC(subServs);
		int priority = 1;

		for (SubServEntity subServ : subServs) {
			SubTaskEntity subTask = new SubTaskEntity();
			subTasks.add(subTask);

			subTask.setId(PrimaryKeyUtils.uniqueId());
			subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_SUBSERV);
			subTask.setObjId(subServ.getId());
			subTask.setObjName(subServ.getSubOrder().getDefinitionSubServ().getName());
			subTask.setObj(subServ);
			subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_REMOVE);
			subTask.setAsync(false);
			subTask.setTimeout(HttpClientUtils.requestConfig.getSocketTimeout() + 10000);
			if (priority == 1) {
				subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
				subTask.setStartDateTime(date);
			} else {
				subTask.setStatus(SubTaskDictConstants.STATUS_NOTRUN);
			}
			if (StringUtils.isNotBlank(subServ.getRelateId())) {
				String url = "/" + SysConstants.MGM_VERSION + "/services/" + subServ.getRelateId();
				subTask.setUrl(url);
			}
			subTask.setMethodType(HttpClientUtils.METHOD_DELETE);
			subTask.setParam(null);
			subTask.setPriority(priority);
			priority++;
		}
		return subTasks;
	}

	/**
	 * 获取服务状态 <br>
	 * 1.子服务状态全是passing时，服务状态为passing。 <br>
	 * 2.子服务状态有一个是critical时，服务状态为critical。 <br>
	 * 3.子服务状态全是未知状态时，服务状态为未知。 <br>
	 * 5.其他情况时，服务状态为warning。
	 * 
	 * @param serv
	 *            服务对象
	 * @param unitMonitorStatusMap
	 * @return 服务状态
	 */
	private String getServStatus(ServEntity serv, Map<String, JSONArray> unitMonitorStatusMap) {
		String status = null;
		int subServPassingCnt = 0;
		int subServCriticalCnt = 0;
		int subServUnknownCnt = 0;
		List<SubServEntity> subServs = serv.getSubServs();
		for (SubServEntity subServ : subServs) {
			JSONArray unitMonitorStatus = unitMonitorStatusMap.get(subServ.getRelateId());
			String subServStatus = subServService
					.getSubServStatus(subServ.getSubOrder().getDefinitionSubServArch().getUnitNum(), unitMonitorStatus);
			switch (subServStatus) {
			case DictConstants.SUBSERV_STATUS_PASSING:
				subServPassingCnt++;
				break;
			case DictConstants.SUBSERV_STATUS_CRITICAL:
				subServCriticalCnt++;
				break;
			case DictConstants.SUBSERV_STATUS_UNKNOWN:
				subServUnknownCnt++;
				break;
			}
		}

		int subServCnt = subServs.size();
		if (subServPassingCnt == subServCnt) {
			status = DictConstants.SERV_STATUS_PASSING;
		} else if (subServCriticalCnt > 0) {
			status = DictConstants.SERV_STATUS_CRITICAL;
		} else if (subServUnknownCnt == subServCnt) {
			status = DictConstants.SERV_STATUS_UNKNOWN;
		} else {
			status = DictConstants.SERV_STATUS_WARNNING;
		}

		return status;
	}

	/**
	 * 获取服务拓扑
	 * 
	 * @param servs
	 *            服务集合
	 * @return Map key:服务编码，value:拓扑
	 */
	private Map<String, JSONObject> getTopology(List<ServEntity> servs) {
		final Map<String, JSONObject> topologyMap = new HashMap<>();
		final CountDownLatch mDoneSignal = new CountDownLatch(servs.size());
		ExecutorService executor = Executors.newFixedThreadPool(servs.size());
		for (final ServEntity serv : servs) {
			executor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						JSONObject topologyInfo = getTopology(serv);
						topologyMap.put(serv.getId(), topologyInfo);
					} catch (Exception e) {
						logger.error(e.getMessage());
					} finally {
						mDoneSignal.countDown();
					}
				}
			});
		}
		try {
			mDoneSignal.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		executor.shutdown();
		return topologyMap;
	}

	/**
	 * 获取服务可用状态
	 * 
	 * @param topologyInfo
	 *            拓扑
	 * @param servType
	 *            服务类型
	 * @return String 服务可用状态
	 * @throws Exception
	 */
	private String getAvailableStatus(JSONObject topologyInfo, String servType) throws Exception {
		String status = DictConstants.SERV_STATUS_UNKNOWN;
		int passingCnt = 0;
		int criticalCnt = 0;
		int subServCnt = 0;
		switch (servType) {
		case SysConstants.SERV_UPSQL_UPPROXY_SWM_CODE:
			if (topologyInfo != null) {
				JSONObject groupInfo = topologyInfo.getJSONObject("datanode_group");
				subServCnt = groupInfo.entrySet().size();
				for (Map.Entry<String, Object> subServ : groupInfo.entrySet()) {
					JSONObject subServInfo = (JSONObject) subServ.getValue();
					int normalCnt = 0;
					int abnormalCnt = 0;
					for (Map.Entry<String, Object> unit : subServInfo.entrySet()) {
						JSONObject unitInfo = (JSONObject) unit.getValue();
						if ("normal".equals(unitInfo.getString("status"))) {
							normalCnt++;
						} else if ("abnormal".equals(unitInfo.getString("status"))) {
							abnormalCnt++;
						}
					}
					if (normalCnt == subServInfo.entrySet().size()) {
						passingCnt++;
					} else if (abnormalCnt == subServInfo.entrySet().size()) {
						criticalCnt++;
					}
				}
			}
			break;

		default:
			return status;
		}
		if (subServCnt != 0) {
			if (passingCnt == subServCnt) {
				status = "passing";
			} else if (criticalCnt > 0) {
				status = "critical";
			} else {
				status = "warning";
			}
		}
		return status;
	}

	private UserEntity findUser(List<UserEntity> users, String username) {
		if (users != null) {
			for (UserEntity user : users) {
				if (user.getUsername().equals(username)) {
					return user;
				}
			}
		}
		return null;
	}

}
